package com.sky.utils;

import com.sky.baidumap.SearchHttpAK;
import com.sky.properties.ConfigLoaderProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.awt.geom.Point2D;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 获取两个地理编码之间的距离
 * @author yangkexuan
 */
@Component
public class LocationUtils {
    public static String URL = "https://api.map.baidu.com/geocoding/v3?";
    public static String AK = "9GOIzdZQdyO4B4hueMZtcUtp6EH1Wupx";
    private ConfigLoaderProperties config;

    @Autowired
    public void ShopService(ConfigLoaderProperties config) {
        this.config = config;
    }

    /**
     * 地球平均半径,单位：m
     */
    private static final double EARTH_RADIUS = 6371393;

    /**
     * 外部调用方法，计算两地距离
     * @throws Exception
     */
    public Double getResult(String useraddress) throws Exception {
        List listAdmin = searchHttpAK(config.getAddress());
        List listUser = searchHttpAK(useraddress);
        return mapGet(listAdmin,listUser);
    }

    /**
     * 获取yml配置的地址
     * @return
     * @throws Exception
     */
    public List<String> searchHttpAK(String address) throws Exception {
        SearchHttpAK snCal = new SearchHttpAK();
        Map params = new LinkedHashMap<String, String>();
        params.put("address", address);
        params.put("output", "json");
        params.put("ak", AK);
        params.put("callback", "showLocation");

        List<String> list = snCal.requestGetAK(URL, params);
        return list;
    }

    /**
     * 百度地图两个经纬度计算距离时间
     * {"status":0,"result":[{"distance":{"text":"289.6公里","value":289578},"duration":{"text":"3.6小时","value":12828}}],"message":"成功"}
     */

    public Double mapGet(List<String> result1,List<String> result2) {
        Double lenAdmin = Double.valueOf(result1.get(0));
        Double latAdmin = Double.valueOf(result1.get(1));
        Double lenUser = Double.valueOf(result2.get(0));
        Double latUser = Double.valueOf(result2.get(1));
        try {
            // 本地地址
            Point2D pointDD = new Point2D.Double(lenAdmin, latAdmin);
            // 用户地址
            Point2D pointXD = new Point2D.Double(lenUser, latUser);
            return getDistance(pointDD, pointXD);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 通过AB点经纬度获取距离
     *
     * @param pointA A点(经，纬)
     * @param pointB B点(经，纬)
     * @return 距离(单位：米)
     */
    public static double getDistance(Point2D pointA, Point2D pointB) {
        // 经纬度（角度）转弧度。弧度用作参数，以调用Math.cos和Math.sin
        // A经弧度
        double radiansAX = Math.toRadians(pointA.getX());
        // A纬弧度
        double radiansAY = Math.toRadians(pointA.getY());
        // B经弧度
        double radiansBX = Math.toRadians(pointB.getX());
        // B纬弧度
        double radiansBY = Math.toRadians(pointB.getY());

        // cosβ1cosβ2cos（α1-α2）+sinβ1sinβ2
        double cos = Math.cos(radiansAY) * Math.cos(radiansBY) * Math.cos(radiansAX - radiansBX)
                + Math.sin(radiansAY) * Math.sin(radiansBY);
        // 反余弦值
        double acos = Math.acos(cos);
        // 最终结果
        return EARTH_RADIUS * acos;
    }
}